home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / unix / pdmake / part02 < prev   
Encoding:
Internet Message Format  |  1990-06-04  |  25.3 KB

  1. Path: wuarchive!swbatl!texbell!texsun!newstop!sun-barr!cs.utexas.edu!sdd.hp.com!uakari.primate.wisc.edu!xanth!cs.odu.edu!Amiga-Request
  2. From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v90i178: pdmake - maintain program groups, Part02/02
  5. Message-ID: <12707@xanth.cs.odu.edu>
  6. Date: 4 Jun 90 00:22:00 GMT
  7. Sender: tadguy@cs.odu.edu
  8. Reply-To: huver@amgraf.uucp
  9. Lines: 1042
  10. Approved: tadguy@cs.odu.edu (Tad Guy)
  11. X-Mail-Submissions-To: Amiga@cs.odu.edu
  12. X-Post-Discussions-To: comp.sys.amiga
  13.  
  14. Submitted-by: huver@amgraf.uucp
  15. Posting-number: Volume 90, Issue 178
  16. Archive-name: unix/pdmake/part02
  17.  
  18. #!/bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 2 (of 2)."
  25. # Contents:  make.c rules.c
  26. # Wrapped by tadguy@xanth on Sun Jun  3 20:20:43 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'make.c' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'make.c'\"
  30. else
  31. echo shar: Extracting \"'make.c'\" \(12008 characters\)
  32. sed "s/^X//" >'make.c' <<'END_OF_FILE'
  33. X/*
  34. X *    Do the actual making for make
  35. X */
  36. X
  37. X#include <stdio.h>
  38. X#ifdef unix
  39. X#include <sys/types.h>
  40. X#include <sys/stat.h>
  41. X#include <sys/errno.h>
  42. X#endif
  43. X#ifdef eon
  44. X#include <sys/stat.h>
  45. X#include <sys/err.h>
  46. X#endif
  47. X#ifdef os9
  48. X#include <time.h>
  49. X#include <os9.h>
  50. X#include <modes.h>
  51. X#include <direct.h>
  52. X#include <errno.h>
  53. X#endif
  54. X#ifdef amiga
  55. X#include <ctype.h>
  56. X#include <errno.h>
  57. X#include <libraries/dosextens.h>
  58. X#include <exec/memory.h>
  59. X#include <exec/io.h>
  60. X#include <exec/ports.h>
  61. X#include <functions.h>
  62. X#undef TRUE            /*OIS*0.80*/
  63. X#undef FALSE            /*OIS*0.80*/
  64. X/*#define ACTION_SET_DATE     34L /*OIS*0.80*/
  65. X#endif
  66. X#include "h.h"
  67. X
  68. X
  69. X
  70. X/*
  71. X *    Exec a shell that returns exit status correctly (/bin/esh).
  72. X *    The standard EON shell returns the process number of the last
  73. X *    async command, used by the debugger (ugg).
  74. X *    [exec on eon is like a fork+exec on unix]
  75. X */
  76. Xint
  77. Xdosh(string, shell)
  78. X    char       *string;
  79. X    char       *shell;
  80. X{
  81. X    int         number;
  82. X
  83. X#ifdef amiga
  84. X    char       *av[3], *s, *p;
  85. X    int         i;
  86. X
  87. X    fflush(stdout); /*OIS*0.80*/
  88. X    if ((p = s = malloc((unsigned) strlen(string) + 1)) == NULL)
  89. X    fatal("No memory for command '%s'", string);
  90. X    strcpy(p, string);                  /* make a copy of the string */
  91. X    i = 0;
  92. X    av[0] = gettok(&p);                 /* get first argument */
  93. X    av[1] = p;                /* get rest of command line */
  94. X    av[2] = NULL;
  95. X    if (fexecv(av[0], av) == -1)
  96. X    fatal("couldn't execute command '%s', error return %02x\n",
  97. X          av[0], errno);
  98. X    number = wait();
  99. X    free(s);
  100. X    return number;
  101. X#endif
  102. X
  103. X#ifdef unix
  104. X    return system(string);
  105. X#endif
  106. X#ifdef eon
  107. X    return ((number = execl(shell, shell, "-c", string, 0)) == -1) ?
  108. X    -1 :            /* couldn't start the shell */
  109. X    wait(number);           /* return its exit status */
  110. X#endif
  111. X#ifdef os9
  112. X    int         status, pid;
  113. X
  114. X    strcat(string, "\n");
  115. X    if ((number = os9fork(shell, strlen(string), string, 0, 0, 0)) == -1)
  116. X    return -1;        /* Couldn't start a shell */
  117. X    do {
  118. X    if ((pid = wait(&status)) == -1)
  119. X        return -1;        /* child already died!?!? */
  120. X    } while (pid != number);
  121. X
  122. X    return status;
  123. X#endif
  124. X}
  125. X
  126. X
  127. X/*
  128. X *    Do commands to make a target
  129. X */
  130. Xvoid
  131. Xdocmds1(np, lp)
  132. X    struct name    *np;
  133. X    struct line    *lp;
  134. X{
  135. X    bool        ssilent;
  136. X    bool        signore;
  137. X    int         estat;
  138. X    register char  *q;
  139. X    register char  *p;
  140. X    char       *shell;
  141. X    register struct cmd *cp;
  142. X#ifdef amiga
  143. X    long SetSignal();
  144. X#endif
  145. X
  146. X#ifndef amiga
  147. X    if (*(shell = getmacro("SHELL")) == '\0')
  148. X#ifdef eon
  149. X    shell = ":bin/esh";
  150. X#endif
  151. X#ifdef unix
  152. X    shell = "/bin/sh";
  153. X#endif
  154. X#ifdef os9
  155. X    shell = "shell";
  156. X#endif
  157. X#else /* for amiga */
  158. X    shell = NULL;
  159. X#endif
  160. X
  161. X    for (cp = lp->l_cmd; cp; cp = cp->c_next) {
  162. X    strcpy(str1, cp->c_cmd);
  163. X    expand(str1);
  164. X    q = str1;
  165. X    ssilent = silent;
  166. X    signore = ignore;
  167. X    while ((*q == '@') || (*q == '-')) {
  168. X        if (*q == '@')      /* Specific silent  */
  169. X        ssilent = TRUE;
  170. X        else        /* Specific ignore  */
  171. X        signore = TRUE;
  172. X        q++;        /* Not part of the command  */
  173. X    }
  174. X
  175. X    if (!domake)
  176. X        ssilent = 0;
  177. X
  178. X    if (!ssilent)
  179. X        fputs("    ", stdout);
  180. X
  181. X    for (p = q; *p; p++) {
  182. X        if (*p == '\n' && p[1] != '\0') {
  183. X        *p = ' ';
  184. X        if (!ssilent)
  185. X            fputs("\\\n", stdout);
  186. X        } else if (!ssilent)
  187. X        putchar(*p);
  188. X    }
  189. X    if (!ssilent)
  190. X        putchar('\n');
  191. X
  192. X    if (domake) {           /* Get the shell to execute it  */
  193. X        if ((estat = dosh(q, shell)) != 0) {
  194. X        if (estat == -1)
  195. X            fatal("Couldn't execute %s", shell);
  196. X        else {
  197. X            printf("%s: Error code %d", myname, estat);
  198. X            if (signore)
  199. X            fputs(" (Ignored)\n", stdout);
  200. X            else {
  201. X            putchar('\n');
  202. X            if (!(np->n_flag & N_PREC))
  203. X                if (unlink(np->n_name) == 0)
  204. X                printf("%s: '%s' removed.\n",
  205. X                    myname, np->n_name);
  206. X            exit(estat);
  207. X            }
  208. X        }
  209. X        }
  210. X#ifdef amiga
  211. X        if ((SetSignal(0L, SIGBREAKF_CTRL_D) & SIGBREAKF_CTRL_D) != 0) {
  212. X        fatal("Abort due to ^D");   /*OIS*0.80*/
  213. X        }
  214. X#endif
  215. X    }
  216. X    }
  217. X}
  218. X
  219. X
  220. Xdocmds(np)
  221. X    struct name    *np;
  222. X{
  223. X    register struct line *lp;
  224. X
  225. X
  226. X    for (lp = np->n_line; lp; lp = lp->l_next)
  227. X    docmds1(np, lp);
  228. X}
  229. X
  230. X
  231. X#ifdef os9
  232. X/*
  233. X *    Some stuffing around to get the modified time of a file
  234. X *    in an os9 file system
  235. X */
  236. Xgetmdate(fd, tbp)
  237. X    struct sgtbuf  *tbp;
  238. X{
  239. X    struct registers regs;
  240. X    static struct fildes fdbuf;
  241. X
  242. X
  243. X    regs.rg_a = fd;
  244. X    regs.rg_b = SS_FD;
  245. X    regs.rg_x = &fdbuf;
  246. X    regs.rg_y = sizeof(fdbuf);
  247. X
  248. X    if (_os9(I_GETSTT, ®s) == -1) {
  249. X    errno = regs.rg_b & 0xff;
  250. X    return -1;
  251. X    }
  252. X    if (tbp) {
  253. X    _strass(tbp, fdbuf.fd_date, sizeof(fdbuf.fd_date));
  254. X    tbp->t_second = 0;    /* Files are only acurate to mins */
  255. X    }
  256. X    return 0;
  257. X}
  258. X
  259. X
  260. X/*
  261. X *    Kludge routine to return an aproximation of how many
  262. X *    seconds since 1980.  Dates will be in order, but will not
  263. X *    be lineer
  264. X */
  265. Xtime_t
  266. Xcnvtime(tbp)
  267. X    struct sgtbuf  *tbp;
  268. X{
  269. X    long        acc;
  270. X
  271. X
  272. X    acc = tbp->t_year - 80;    /* Baseyear is 1980 */
  273. X    acc = acc * 12 + tbp->t_month;
  274. X    acc = acc * 31 + tbp->t_day;
  275. X    acc = acc * 24 + tbp->t_hour;
  276. X    acc = acc * 60 + tbp->t_minute;
  277. X    acc = acc * 60 + tbp->t_second;
  278. X
  279. X    return acc;
  280. X}
  281. X
  282. X
  283. X/*
  284. X *    Get the current time in the internal format
  285. X */
  286. Xtime(tp)
  287. X    time_t       *tp;
  288. X{
  289. X    struct sgtbuf   tbuf;
  290. X
  291. X
  292. X    if (getime(&tbuf) < 0)
  293. X    return -1;
  294. X
  295. X    if (tp)
  296. X    *tp = cnvtime(&tbuf);
  297. X
  298. X    return 0;
  299. X}
  300. X#endif
  301. X
  302. X
  303. X/*
  304. X *    Get the modification time of a file.  If the first
  305. X *    doesn't exist, it's modtime is set to 0.
  306. X */
  307. Xvoid
  308. Xmodtime(np)
  309. X    struct name    *np;
  310. X{
  311. X#ifdef unix
  312. X    struct stat     info;
  313. X    int         fd;
  314. X
  315. X
  316. X    if (stat(np->n_name, &info) < 0) {
  317. X    if (errno != ENOENT)
  318. X        fatal("Can't open %s; error %d", np->n_name, errno);
  319. X
  320. X    np->n_time = 0L;
  321. X    } else
  322. X    np->n_time = info.st_mtime;
  323. X#endif
  324. X#ifdef eon
  325. X    struct stat     info;
  326. X    int         fd;
  327. X
  328. X
  329. X    if ((fd = open(np->n_name, 0)) < 0) {
  330. X    if (errno != ER_NOTF)
  331. X        fatal("Can't open %s; error %02x", np->n_name, errno);
  332. X
  333. X    np->n_time = 0L;
  334. X    } else if (getstat(fd, &info) < 0)
  335. X    fatal("Can't getstat %s; error %02x", np->n_name, errno);
  336. X    else
  337. X    np->n_time = info.st_mod;
  338. X
  339. X    close(fd);
  340. X#endif
  341. X#ifdef os9
  342. X    struct sgtbuf   info;
  343. X    int         fd;
  344. X
  345. X
  346. X    if ((fd = open(np->n_name, 0)) < 0) {
  347. X    if (errno != E_PNNF)
  348. X        fatal("Can't open %s; error %02x", np->n_name, errno);
  349. X
  350. X    np->n_time = 0L;
  351. X    } else if (getmdate(fd, &info) < 0)
  352. X    fatal("Can't getstat %s; error %02x", np->n_name, errno);
  353. X    else
  354. X    np->n_time = cnvtime(&info);
  355. X
  356. X    close(fd);
  357. X#endif
  358. X#ifdef amiga
  359. X    struct FileInfoBlock *fib;
  360. X    struct FileLock *myLock;
  361. X    long ioErr;
  362. X
  363. X    fib = (struct FileInfoBlock *) malloc((unsigned) sizeof(struct FileInfoBlock));
  364. X    if ((myLock = Lock(np->n_name, ACCESS_READ)) == NULL) {
  365. X    if ((ioErr = IoErr()) != ERROR_OBJECT_NOT_FOUND)
  366. X        fatal("Can't Lock '%s'; error %3ld", np->n_name, ioErr);
  367. X    np->n_time = 0L;
  368. X    } else if (!Examine(myLock, fib)) {
  369. X    UnLock(myLock);
  370. X    fatal("Can't Examine '%s'; error %3ld", np->n_name, IoErr());
  371. X    } else {
  372. X    np->n_time = fib->fib_Date.ds_Tick/TICKS_PER_SECOND +
  373. X         60*fib->fib_Date.ds_Minute + 86400*fib->fib_Date.ds_Days;
  374. X    UnLock(myLock);
  375. X    }
  376. X    free((char *) fib);
  377. X#endif
  378. X
  379. X}
  380. X
  381. X#ifdef amiga
  382. Xchar *
  383. Xnametail(name)
  384. Xregister char *name;
  385. X{
  386. X    register char *tail;
  387. X
  388. X    if ((tail = index(name, ':')) == NULL)      /* strip device name */
  389. X    tail = name;
  390. X    if ((name = rindex(tail, '/')) == NULL)     /* strip directories */
  391. X    name = tail;
  392. X
  393. X    return name;
  394. X}
  395. X#endif
  396. X
  397. X
  398. X/*
  399. X *    Update the mod time of a file to now.
  400. X */
  401. Xvoid
  402. Xtouch(np)
  403. X    struct name    *np;
  404. X{
  405. X    char        c;
  406. X    int         fd;
  407. X
  408. X
  409. X    if (!domake || !silent)
  410. X    printf("    touch(%s)\n", np->n_name);
  411. X
  412. X    if (domake) {
  413. X#ifdef unix
  414. X    long        a[2];
  415. X
  416. X    a[0] = a[1] = time(0);
  417. X    if (utime(np->n_name, &a[0]) < 0)
  418. X        printf("%s: '%s' not touched - non-existant\n",
  419. X           myname, np->n_name);
  420. X#endif
  421. X#ifdef eon
  422. X    if ((fd = open(np->n_name, 0)) < 0)
  423. X        printf("%s: '%s' not touched - non-existant\n",
  424. X           myname, np->n_name);
  425. X    else {
  426. X        uread(fd, &c, 1, 0);
  427. X        uwrite(fd, &c, 1);
  428. X    }
  429. X    close(fd);
  430. X#endif
  431. X#ifdef os9
  432. X    /*
  433. X     * Strange that something almost as totally useless as this is easy
  434. X     * to do in os9!
  435. X     */
  436. X    if ((fd = open(np->n_name, S_IWRITE)) < 0)
  437. X        printf("%s: '%s' not touched - non-existant\n",
  438. X           myname, np->n_name);
  439. X    close(fd);
  440. X#endif
  441. X#ifdef amiga
  442. X    struct MsgPort *task;
  443. X    ULONG dateStamp[3];
  444. X    struct FileLock *lock, *plock;
  445. X    UBYTE *bcplstring;
  446. X
  447. X    if(!(bcplstring = (UBYTE *)AllocMem(64L, MEMF_PUBLIC)))
  448. X        fatal("Can't get 64 bytes for bcplstring");
  449. X    if(!(task=(struct MsgPort *)DeviceProc(np->n_name))) {
  450. X        printf("%s: can't get MsgPort for '%s'\n", myname, np->n_name);
  451. X        goto abort;
  452. X    }
  453. X    if(!(lock = Lock(np->n_name, SHARED_LOCK))) {
  454. X        printf("%s: '%s' not touched - non-existant\n",
  455. X            myname, np->n_name);
  456. X        goto abort;
  457. X    }
  458. X    plock = ParentDir(lock);
  459. X    UnLock(lock);
  460. X
  461. X    /* Strip pathnames first */
  462. X    strcpy((bcplstring + 1), nametail(np->n_name));
  463. X    *bcplstring = strlen(bcplstring + 1);
  464. X
  465. X    dos_packet(task, ACTION_SET_DATE, NULL, plock, (ULONG)bcplstring >> 2,
  466. X        (ULONG) DateStamp(dateStamp), 0L, 0L, 0L);
  467. X
  468. X    UnLock(plock);
  469. Xabort:
  470. X    FreeMem((void *) bcplstring, 64L);
  471. X#endif
  472. X    }
  473. X}
  474. X
  475. X/*
  476. X * Recursive routine to make a target.
  477. X */
  478. Xint
  479. Xmake(np, level)
  480. X    struct name    *np;
  481. X    int         level;
  482. X{
  483. X    register struct depend *dp;
  484. X    register struct line *lp;
  485. X    register struct depend *qdp;
  486. X    time_t        dtime = 1, time();
  487. X    bool        didsomething = 0;
  488. X    char *        basename  = (char *) 0;
  489. X    char *        inputname = (char *) 0;
  490. X
  491. X
  492. X    if (np->n_flag & N_DONE)
  493. X    return 0;
  494. X
  495. X    if (!np->n_time)
  496. X    modtime(np);            /* Gets modtime of this file  */
  497. X
  498. X    if (rules) {
  499. X    for (lp = np->n_line; lp; lp = lp->l_next)
  500. X        if (lp->l_cmd) break;
  501. X
  502. X    if (!lp) dyndep(np, &basename, &inputname);
  503. X    }
  504. X
  505. X    if (!(np->n_flag & N_TARG) && np->n_time == 0L) {
  506. X#if 0
  507. X    fatal("Don't know how to make %s", np->n_name);
  508. X#endif
  509. X        fprintf(stderr,"%s: ", myname);
  510. X        fprintf(stderr,"Don't know how to make %s\n", np->n_name);
  511. X    return 0;
  512. X    }
  513. X
  514. X    for (qdp = (struct depend *) 0, lp = np->n_line; lp; lp = lp->l_next) {
  515. X    for (dp = lp->l_dep; dp; dp = dp->d_next) {
  516. X        make(dp->d_name, level + 1);
  517. X        if (np->n_time < dp->d_name->n_time)
  518. X        qdp = newdep(dp->d_name, qdp);
  519. X        dtime = max(dtime, dp->d_name->n_time);
  520. X    }
  521. X    if (!quest && (np->n_flag & N_DOUBLE) && (np->n_time < dtime)) {
  522. X        make1(np, lp, qdp, basename, inputname); /* free()'s qdp */
  523. X        dtime = 1;
  524. X        qdp = (struct depend *) 0;
  525. X        didsomething++;
  526. X    }
  527. X    }
  528. X
  529. X    np->n_flag |= N_DONE;
  530. X
  531. X    if (quest) {
  532. X    long        t;
  533. X
  534. X    t = np->n_time;
  535. X    time(&np->n_time);
  536. X    if (basename)
  537. X        free(basename);
  538. X
  539. X    return t < dtime;
  540. X    } else if (np->n_time < dtime && !(np->n_flag & N_DOUBLE)) {
  541. X    make1(np, (struct line *)0, qdp, basename, inputname);/* free()'s qdp */
  542. X    time(&np->n_time);
  543. X    } else if (level == 0 && !didsomething)
  544. X    printf("%s: '%s' is up to date\n", myname, np->n_name);
  545. X
  546. X    if (basename)
  547. X    free(basename);
  548. X
  549. X    return 0;
  550. X}
  551. X
  552. X
  553. Xmake1(np, lp, qdp, basename, inputname)
  554. X    register struct depend *qdp;
  555. X    struct line    *lp;
  556. X    struct name    *np;
  557. X    char       *basename;
  558. X    char       *inputname;
  559. X{
  560. X    register struct depend *dp;
  561. X
  562. X
  563. X    if (dotouch)
  564. X    touch(np);
  565. X    else {
  566. X    strcpy(str1, "");
  567. X    if (!basename)
  568. X        basename = str1;
  569. X    setmacro("*", basename);        /* $* = file */
  570. X    if (!inputname)
  571. X        inputname = str1;
  572. X    setmacro("<", inputname);       /* $< = path/file.c or file.c */
  573. X    for (dp = qdp; dp; dp = qdp) {
  574. X        if (strlen(str1))
  575. X        strcat(str1, " ");
  576. X        strcat(str1, dp->d_name->n_name);
  577. X        qdp = dp->d_next;
  578. X        free(dp);
  579. X    }
  580. X    setmacro("?", str1);            /* $? = file.c file1.h file2.h */
  581. X    setmacro("@", np->n_name);      /* $@ = file.o */
  582. X    if (lp)                 /* lp set if doing a :: rule */
  583. X        docmds1(np, lp);
  584. X    else
  585. X        docmds(np);
  586. X    }
  587. X}
  588. X#ifdef amiga
  589. X/*
  590. X * Replace the Aztec-provided time function with one which returns something
  591. X * easy to find and compare, namely the number of seconds since the Amiga's
  592. X * reference date.  This is the same thing returned by modtime() above.
  593. X */
  594. Xtime_t
  595. Xtime(v)
  596. X    time_t *v;
  597. X{
  598. X    long t[3];
  599. X
  600. X    DateStamp(t);
  601. X    t[0] = t[2]/TICKS_PER_SECOND + 60*t[1] + 86400*t[0];
  602. X    if (v)
  603. X    *v = t[0];
  604. X    return t[0];
  605. X}
  606. X#endif
  607. END_OF_FILE
  608. if test 12008 -ne `wc -c <'make.c'`; then
  609.     echo shar: \"'make.c'\" unpacked with wrong size!
  610. fi
  611. # end of 'make.c'
  612. fi
  613. if test -f 'rules.c' -a "${1}" != "-c" ; then 
  614.   echo shar: Will not clobber existing file \"'rules.c'\"
  615. else
  616. echo shar: Extracting \"'rules.c'\" \(10453 characters\)
  617. sed "s/^X//" >'rules.c' <<'END_OF_FILE'
  618. X/*
  619. X *    Control of the implicit suffix rules
  620. X */
  621. X
  622. X
  623. X#include "h.h"
  624. X#ifndef NULL
  625. X#define NULL ((void *) 0)
  626. X#endif
  627. X
  628. X/* -- hu: define the fake target suffix .~ if we will not see any suffix */
  629. Xstatic char *dot_out = ".~";
  630. X
  631. X/*
  632. X *    Dynamic dependency.  This routine applies the suffix rules
  633. X *    to try and find a source and a set of rules for a missing
  634. X *    target.  If found, np is made into a target with the implicit
  635. X *    source name, and rules.  Returns TRUE if np was made into
  636. X *    a target.
  637. X */
  638. Xbool
  639. Xdyndep(np, pbasename, pinputname)
  640. X    struct name    *np;
  641. X    char      **pbasename;    /*  Name without suffix  */
  642. X    char      **pinputname;
  643. X{
  644. X    register char  *p;
  645. X    register char  *q;
  646. X    register char  *suff;    /* Old suffix  */
  647. X    register char  *basename;    /* Name without suffix    */
  648. X    struct name    *op;     /* New dependent  */
  649. X    struct name    *sp;     /* Suffix  */
  650. X    struct line    *lp;
  651. X    struct depend  *dp;
  652. X    struct name    *pathnp;    /* .PATH */
  653. X    struct line    *pathlp;
  654. X    struct depend  *pathdp;
  655. X    struct depend  *pathdp1;
  656. X    char       *newsuff;
  657. X    char       *path;
  658. X    void        modtime();
  659. X
  660. X
  661. X    p = str1;
  662. X    q = np->n_name;
  663. X
  664. X    /* -- hu: if no suffix, pretend the suffix is dot_out */
  665. X    if ((suff = rindex(q, '.')) == NULL) {
  666. X    strcpy (p, q);
  667. X    suff = dot_out;
  668. X    }
  669. X    else {
  670. X    while (q < suff) *p++ = *q++;
  671. X    *p = '\0';
  672. X    }
  673. X
  674. X    if ((*pbasename = basename = malloc(strlen(str1)+1)) == NULL)
  675. X    fatal("No memory for basename");
  676. X    strcpy(*pbasename, str1);
  677. X
  678. X    if (!((sp = newname(".SUFFIXES"))->n_flag & N_TARG))
  679. X    return FALSE;
  680. X
  681. X    if (!((pathnp = newname(".PATH"))->n_flag & N_TARG))
  682. X    pathnp = NULL;
  683. X
  684. X    if ((pathnp) && (pathlp = pathnp->n_line))
  685. X    pathdp = pathlp->l_dep;
  686. X    else
  687. X    pathdp = NULL;
  688. X
  689. X    for (lp = sp->n_line; lp; lp = lp->l_next)
  690. X    for (dp = lp->l_dep; dp; dp = dp->d_next) {
  691. X        newsuff = dp->d_name->n_name;   /* .c .o .asm etc */
  692. X
  693. X        if (strlen(suff) + strlen(newsuff) + 1 >= LZ)
  694. X        fatal("Suffix rule too long");
  695. X        p = str1;
  696. X        q = newsuff;
  697. X        while (*p++ = *q++);
  698. X        p--;
  699. X        q = suff;
  700. X        while (*p++ = *q++);
  701. X
  702. X        sp = newname(str1);     /* Form for example .c.o */
  703. X        if (sp->n_flag & N_TARG) {
  704. X        path = "";
  705. X        pathdp1 = pathdp;
  706. X    nextpath:
  707. X        p = str1;
  708. X        if (strlen(path) + strlen(basename) + strlen(newsuff) + 2 >= LZ)
  709. X            fatal("Implicit name too long");
  710. X        q = path;
  711. X        while (*p++ = *q++);    /* copy path */
  712. X        p--;
  713. X        q = basename;
  714. X        while (*p++ = *q++);    /* copy basename */
  715. X        p--;
  716. X        q = newsuff;
  717. X        while (*p++ = *q++);    /* copy new suffix */
  718. X        op = newname(str1);
  719. X
  720. X        if (!op->n_line && !op->n_time)
  721. X            modtime(op);
  722. X        if (op->n_line || op->n_time) {     /* file exists? */
  723. X            dp = newdep(op, NULL);
  724. X            newline(np, dp, sp->n_line->l_cmd, 0);
  725. X            *pinputname = op->n_name;    /* $< = path/basename.suffix */
  726. X            return TRUE;
  727. X        } else {
  728. X            delname(op);        /* Forget non-existing file */
  729. X            if (pathdp1) {      /* But is there a path? */
  730. X            path = pathdp1->d_name->n_name;
  731. X            pathdp1 = pathdp1->d_next;
  732. X            goto nextpath;
  733. X            }
  734. X        }
  735. X        }
  736. X    }
  737. X    return FALSE;
  738. X}
  739. X
  740. X
  741. X/*
  742. X *    Make the default rules
  743. X */
  744. Xvoid
  745. Xmakerules()
  746. X{
  747. X    register struct cmd     *cp;    /*OIS*0.80*/
  748. X    register struct name    *np;    /*OIS*0.80*/
  749. X    register struct depend  *dp;    /*OIS*0.80*/
  750. X
  751. X#ifdef eon
  752. X    setmacro("BDSCC", "asm");
  753. X    /* setmacro("BDSCFLAGS", "");        */
  754. X    cp = newcmd("$(BDSCC) $(BDSCFLAGS) -n $<", 0);
  755. X    np = newname(".c.o");
  756. X    newline(np, 0, cp, 0);
  757. X
  758. X    setmacro("CC", "c");
  759. X    setmacro("CFLAGS", "-O");
  760. X    cp = newcmd("$(CC) $(CFLAGS) -c $<", 0);
  761. X    np = newname(".c.obj");
  762. X    newline(np, 0, cp, 0);
  763. X
  764. X    setmacro("M80", "asm -n");
  765. X    /* setmacro("M80FLAGS", "");         */
  766. X    cp = newcmd("$(M80) $(M80FLAGS) $<", 0);
  767. X    np = newname(".mac.o");
  768. X    newline(np, 0, cp, 0);
  769. X
  770. X    setmacro("AS", "zas");
  771. X    /* setmacro("ASFLAGS", "");  */
  772. X    cp = newcmd("$(ZAS) $(ASFLAGS) -o $@ $<", 0);
  773. X    np = newname(".as.obj");
  774. X    newline(np, 0, cp, 0);
  775. X
  776. X    np = newname(".as");
  777. X    dp = newdep(np, 0);
  778. X    np = newname(".obj");
  779. X    dp = newdep(np, dp);
  780. X    np = newname(".c");
  781. X    dp = newdep(np, dp);
  782. X    np = newname(".o");
  783. X    dp = newdep(np, dp);
  784. X    np = newname(".mac");
  785. X    dp = newdep(np, dp);
  786. X    np = newname(".SUFFIXES");
  787. X    newline(np, dp, 0, 0);
  788. X#endif
  789. X
  790. X/*
  791. X *    Some of the UNIX implicit rules
  792. X */
  793. X#ifdef unix
  794. X    setmacro("CC", "cc");
  795. X    setmacro("CFLAGS", "-O");
  796. X#ifdef MINIXPC
  797. X    cp = newcmd("$(CC) $(CFLAGS) -S $<", (struct cmd *)0);
  798. X    np = newname(".c.s");
  799. X#else
  800. X    cp = newcmd("$(CC) $(CFLAGS) -c $<", (struct cmd *)0);
  801. X    np = newname(".c.o");
  802. X#endif MINIXPC
  803. X    newline(np, (struct depend *)0, cp, 0);
  804. X
  805. X    setmacro("AS", "as");
  806. X    cp = newcmd("$(AS) -o $@ $<", (struct cmd *)0);
  807. X    np = newname(".s.o");
  808. X    newline(np, (struct depend *)0, cp, 0);
  809. X
  810. X    setmacro("YACC", "yacc");
  811. X    /*        setmacro("YFLAGS", ""); */
  812. X    cp = newcmd("$(YACC) $(YFLAGS) $<", (struct cmd *)0);
  813. X    cp = newcmd("mv y.tab.c $@", cp);
  814. X    np = newname(".y.c");
  815. X    newline(np, (struct depend *)0, cp, 0);
  816. X
  817. X    cp = newcmd("$(YACC) $(YFLAGS) $<", (struct cmd *)0);
  818. X#ifdef MINIXPC
  819. X    cp = newcmd("$(CC) $(CFLAGS) -S y.tab.c", cp);
  820. X    cp = newcmd("mv y.tab.s $@", cp);
  821. X    np = newname(".y.s");
  822. X#else
  823. X    cp = newcmd("$(CC) $(CFLAGS) -c y.tab.c", cp);
  824. X    cp = newcmd("mv y.tab.o $@", cp);
  825. X    np = newname(".y.o");
  826. X#endif MINIXPC
  827. X    cp = newcmd("rm y.tab.c", cp);
  828. X    newline(np, (struct depend *)0, cp, 0);
  829. X
  830. X    setmacro("FLEX", "flex");
  831. X    cp = newcmd("$(FLEX) $(FLEX_FLAGS) $<", (struct cmd *)0);
  832. X    cp = newcmd("mv lex.yy.c $@", cp);
  833. X    np = newname(".l.c");
  834. X    newline(np, (struct depend *)0, cp, 0);
  835. X
  836. X    cp = newcmd("$(FLEX) $(FLEX_FLAGS) $<", (struct cmd *)0);
  837. X#ifdef MINIXPC
  838. X    cp = newcmd("$(CC) $(CFLAGS) -S lex.yy.s", cp);
  839. X    cp = newcmd("mv lex.yy.s $@", cp);
  840. X    np = newname(".l.s");
  841. X#else
  842. X    cp = newcmd("$(CC) $(CFLAGS) -c lex.yy.c", cp);
  843. X    cp = newcmd("mv lex.yy.o $@", cp);
  844. X    np = newname(".l.o");
  845. X#endif MINIXPC
  846. X    cp = newcmd("rm lex.yy.c", cp);
  847. X    newline(np, (struct depend *)0, cp, 0);
  848. X
  849. X    np = newname(".o");
  850. X    dp = newdep(np, (struct depend *)0);
  851. X    np = newname(".s");
  852. X    dp = newdep(np, dp);
  853. X    np = newname(".c");
  854. X    dp = newdep(np, dp);
  855. X    np = newname(".y");
  856. X    dp = newdep(np, dp);
  857. X    np = newname(".l");
  858. X    dp = newdep(np, dp);
  859. X    np = newname(".SUFFIXES");
  860. X    newline(np, dp, (struct cmd *)0, 0);
  861. X#endif
  862. X
  863. X#ifdef os9
  864. X/*
  865. X *    Fairlight use an enhanced version of the C sub-system.
  866. X *    They have a specialised macro pre-processor.
  867. X */
  868. X    setmacro("CC", "cc");
  869. X    setmacro("CFLAGS", "-z");
  870. X    cp = newcmd("$(CC) $(CFLAGS) -r $<", 0);
  871. X
  872. X    np = newname(".c.r");
  873. X    newline(np, 0, cp, 0);
  874. X    np = newname(".ca.r");
  875. X    newline(np, 0, cp, 0);
  876. X    np = newname(".a.r");
  877. X    newline(np, 0, cp, 0);
  878. X    np = newname(".o.r");
  879. X    newline(np, 0, cp, 0);
  880. X    np = newname(".mc.r");
  881. X    newline(np, 0, cp, 0);
  882. X    np = newname(".mca.r");
  883. X    newline(np, 0, cp, 0);
  884. X    np = newname(".ma.r");
  885. X    newline(np, 0, cp, 0);
  886. X    np = newname(".mo.r");
  887. X    newline(np, 0, cp, 0);
  888. X
  889. X    np = newname(".r");
  890. X    dp = newdep(np, 0);
  891. X    np = newname(".mc");
  892. X    dp = newdep(np, dp);
  893. X    np = newname(".mca");
  894. X    dp = newdep(np, dp);
  895. X    np = newname(".c");
  896. X    dp = newdep(np, dp);
  897. X    np = newname(".ca");
  898. X    dp = newdep(np, dp);
  899. X    np = newname(".ma");
  900. X    dp = newdep(np, dp);
  901. X    np = newname(".mo");
  902. X    dp = newdep(np, dp);
  903. X    np = newname(".o");
  904. X    dp = newdep(np, dp);
  905. X    np = newname(".a");
  906. X    dp = newdep(np, dp);
  907. X    np = newname(".SUFFIXES");
  908. X    newline(np, dp, 0, 0);
  909. X#endif
  910. X
  911. X#ifdef amiga
  912. X
  913. X#ifdef pdc    /*OIS*0.80*/
  914. X    static char ccx_c[] = "ccx -c";
  915. X
  916. X    setmacro("CC", ccx_c);
  917. X#else
  918. X    setmacro("CC", "cc");
  919. X#endif
  920. X    cp = newcmd("$(CC) $(CFLAGS) $<", NULL);
  921. X    np = newname(".c.o");
  922. X    newline(np, NULL, cp, 0);
  923. X
  924. X#ifdef pdc    /*OIS*0.80*/
  925. X    setmacro("AS", ccx_c);
  926. X    cp = newcmd("$(AS) $(AFLAGS) $<", NULL);        /*OIS*0.80*/
  927. X#else
  928. X    setmacro("AS", "as");
  929. X    cp = newcmd("$(AS) $(AFLAGS) -o $@ $<", NULL);  /*OIS*0.80*/
  930. X#endif
  931. X    np = newname(".s.o");
  932. X    newline(np, NULL, cp, NULL);
  933. X    np = newname(".a.o");
  934. X    newline(np, NULL, cp, NULL);
  935. X
  936. X    /* -- hu: provide .asm suffix recognition -- */
  937. X    np = newname(".asm.o");
  938. X    newline(np, NULL, cp, NULL);
  939. X
  940. X    /* -- hu: add definitions to call the linker, and generate executable
  941. X     *        from .o file.  This is done by using fake suffix `dot_out'
  942. X     *        to qualify the target executable.  Setup for MANX 3.6 only,
  943. X     *        but you can easily see what I'm doing here and add for
  944. X     *        other "brands".
  945. X    */
  946. X#ifdef pdc
  947. X/*
  948. X*/
  949. X#endif
  950. X#ifdef manx
  951. X    setmacro("LD", "ln");
  952. X    setmacro("LDLIBS", "-lc");
  953. X    cp = newcmd("$(LD) $(LDFLAGS) -o $@ $< $(LDLIBS)", NULL);
  954. X#endif
  955. X    np = newname(".o.~");
  956. X    newline(np, NULL, cp, NULL);
  957. X
  958. X    /* -- hu: add rules for making executable from source.  This is not
  959. X     *          pretty (two-step approach) but is easier.
  960. X    */
  961. X    /* -- hu: from .c to .~ */
  962. X    np = newname(".c.~");
  963. X    cp = newcmd("$(CC) $(CFLAGS) $<", NULL);
  964. X#ifdef pdc
  965. X/*
  966. X*/
  967. X#endif
  968. X#ifdef manx
  969. X    cp = newcmd("$(LD) $(LDFLAGS) -o $@ $@.o $(LDLIBS)", cp);
  970. X#endif
  971. X    newline(np, NULL, cp, NULL);
  972. X
  973. X    /* -- hu: from .a to .~ */
  974. X    np = newname(".a.~");
  975. X#ifdef pdc    /*OIS*0.80*/
  976. X/*
  977. X*/
  978. X#endif
  979. X#ifdef manx
  980. X    cp = newcmd("$(AS) $(AFLAGS) -o $@ $<", NULL);
  981. X    cp = newcmd("$(LD) $(LDFLAGS) -o $@ $@.o $(LDLIBS)", cp);
  982. X#endif
  983. X    newline(np, NULL, cp, NULL);
  984. X    
  985. X    /* -- hu: from .s to .~ */
  986. X    np = newname(".s.~");
  987. X#ifdef pdc    /*OIS*0.80*/
  988. X/*
  989. X*/
  990. X#endif
  991. X#ifdef mnax
  992. X    cp = newcmd("$(AS) $(AFLAGS) -o $@ $<", NULL);
  993. X    cp = newcmd("$(LD) $(LDFLAGS) -o $@ $@.o $(LDLIBS)", cp);
  994. X#endif
  995. X    newline(np, NULL, cp, NULL);
  996. X
  997. X    /* -- hu: and from .asm to .~ */
  998. X    np = newname(".asm.~");
  999. X#ifdef pdc    /*OIS*0.80*/
  1000. X/*
  1001. X*/
  1002. X#endif
  1003. X#ifdef manx
  1004. X    cp = newcmd("$(AS) $(AFLAGS) -o $@ $<", NULL);
  1005. X    cp = newcmd("$(LD) $(LDFLAGS) -o $@ $@.o $(LDLIBS)", cp);
  1006. X#endif
  1007. X    newline(np, NULL, cp, NULL);
  1008. X
  1009. X    /* -- hu: insert .~ in the .SUFFIX list; also changed dependency
  1010. X     *        order to be: .~ .o .a .asm .s .c
  1011. X    */
  1012. X    np = newname(".~");
  1013. X    dp = newdep(np, NULL);
  1014. X    np = newname(".o");
  1015. X    dp = newdep(np, NULL);
  1016. X    dp = newdep(np, dp);
  1017. X    np = newname(".a");
  1018. X    dp = newdep(np, dp);
  1019. X    np = newname(".asm");
  1020. X    dp = newdep(np, dp);
  1021. X    np = newname(".s");
  1022. X    dp = newdep(np, dp);
  1023. X    np = newname(".c");
  1024. X    dp = newdep(np, dp);
  1025. X    np = newname(".SUFFIXES");
  1026. X    newline(np, dp, NULL, 0);
  1027. X#endif
  1028. X}
  1029. END_OF_FILE
  1030. if test 10453 -ne `wc -c <'rules.c'`; then
  1031.     echo shar: \"'rules.c'\" unpacked with wrong size!
  1032. fi
  1033. # end of 'rules.c'
  1034. fi
  1035. echo shar: End of archive 2 \(of 2\).
  1036. cp /dev/null ark2isdone
  1037. MISSING=""
  1038. for I in 1 2 ; do
  1039.     if test ! -f ark${I}isdone ; then
  1040.     MISSING="${MISSING} ${I}"
  1041.     fi
  1042. done
  1043. if test "${MISSING}" = "" ; then
  1044.     echo You have unpacked both archives.
  1045.     rm -f ark[1-9]isdone
  1046. else
  1047.     echo You still need to unpack the following archives:
  1048.     echo "        " ${MISSING}
  1049. fi
  1050. ##  End of shell archive.
  1051. exit 0
  1052. -- 
  1053. Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
  1054. Mail comments to the moderator at <amiga-request@cs.odu.edu>.
  1055. Post requests for sources, and general discussion to comp.sys.amiga.
  1056.